package com.parking.order.task;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.parking.common.core.model.StateData;
import com.parking.common.core.util.DateUtil;
import com.parking.order.client.dto.CertifiedInfoDto;
import com.parking.order.client.dto.CertifiedScoreDto;
import com.parking.order.client.form.CertifiedScoreForm;
import com.parking.order.dao.OrderCommentDao;
import com.parking.order.dao.OrderInfoDao;
import com.parking.order.model.OrderComment;
import com.parking.order.model.OrderInfo;
import com.parking.order.service.IOrderCommentService;
import com.parking.order.service.IOrderInfoService;
import com.parking.order.util.BasicInfoUtil;
import com.parking.order.util.RegularTimeUtil;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.swing.plaf.nimbus.State;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 评论定时任务类
 * */
@Component
public class CommentTask {
    /**
     * 订单信息数据层
     * */
    @Autowired
    private OrderInfoDao orderInfoDao;
    /**
     * 订单评论服务层
     * */
    @Autowired
    private IOrderCommentService orderCommentService;
    /**
     * 订单信息服务层
     * */
    @Autowired
    private IOrderInfoService orderInfoService;
    /**
     * 订单评论数据层
     * */
    @Autowired
    private OrderCommentDao orderCommentDao;
    /**
     * 消息队列
     * */
    @Autowired
    private RabbitTemplate rabbitTemplate;
    /**
     * 其他模块调用工具类
     * */
    @Autowired
    private BasicInfoUtil basicInfoUtil;
    /**
     * 到期自动评论
     * 定时时间 00/15/30/45分钟时执行一次
     * */
    @Transactional
    @XxlJob("automaticComment")
    public void automaticComment(){
        String time = XxlJobHelper.getJobParam();
        System.out.println("任务参数:"+time);
        System.out.println("====================开始自动评论任务==========================");

        LocalDateTime now = null;
        if(time==null||time.equals("")){
            now = RegularTimeUtil.getStandardTime();
        }else{
            now = DateUtil.stringToLocalDateTime(time,"yyyy-MM-dd HH:mm");
        }

        System.out.println("现在时间:"+now);

        LocalDateTime checkTime = now.minusDays(StateData.AUTOMATIC_COMMENT_LENGTH_DAY);
        System.out.println("7天前的时间:"+checkTime);

        // 完成订单 未超时或超时已支付 未评论 最后一次修改时间足够久
        System.out.println("开始生成wrapper");
        QueryWrapper<OrderInfo> wrapper = new QueryWrapper<OrderInfo>().eq("order_info_state", StateData.ORDER_STATE_END).in("is_overtime", Arrays.asList(StateData.ORDER_IS_OVERTIME_FINISH, StateData.ORDER_IS_NOT_OVERTIME)).eq("is_comment", StateData.ORDER_IS_NOT_COMMENT).le("order_update_time", checkTime);
        System.out.println("生成wrapper结束");

        System.out.println("开始查询订单");
        List<OrderInfo> orders = orderInfoDao.selectList(wrapper);
        System.out.println("查询订单结束");

        if(orders.isEmpty()){
            System.out.println("查询出来订单是空集 自动评论任务结束");
        }

        for (OrderInfo order : orders) {
            System.out.println("订单编号:"+order.getOrderInfoNum());
        }


        if(!orders.isEmpty()){
            // 自动生成评论
            List<OrderComment> comments = new ArrayList<>();
            for (OrderInfo order : orders) {
                // orderInfoId userInfoId commentInfo commentTime replyId=certifiedInfoId orderInfoNum commentScore
                OrderComment comment = new OrderComment(order.getOrderInfoId(),order.getUserInfoId(),"系统自动默认好评",now,order.getCertifiedInfoId(),order.getOrderInfoNum(),StateData.COMMENT_SCORE_GOOD);
                comments.add(comment);

                order.setIsComment(StateData.ORDER_IS_COMMENT_NO_REPLY);
                order.setOrderUpdateTime(now);
                order.setCommentScore("Good");
            }
            orderCommentService.saveBatch(comments);
            orderInfoService.saveBatch(orders);

            // 添加订单日志
            StringBuilder orderIdsStr = new StringBuilder();
            for (OrderInfo order : orders) {
                if(!orderIdsStr.toString().equals("")) orderIdsStr.append(",");
                orderIdsStr.append(order.getOrderInfoId());
            }
            rabbitTemplate.convertAndSend("orderLogBatch",orderIdsStr+",用户完成订单后"+ StateData.AUTOMATIC_COMMENT_LENGTH_DAY +"天未评论 系统自动好评,0,系统自动");

        }
    }
    /**
     * 计算物业评分
     * 定时任务 每天0点执行一次
     * */
    @XxlJob("commentScore")
    public void commentScore() throws Exception {
        List<CertifiedInfoDto> certifieds = basicInfoUtil.getAllCertifiedInfo();

        if(!certifieds.isEmpty()){
            List<OrderComment> comments = orderCommentDao.selectList(new QueryWrapper<OrderComment>().eq("reply_id",certifieds.stream().map(CertifiedInfoDto::getCertifiedInfoId).collect(Collectors.toList())).gt("comment_time",LocalDateTime.now().minusDays(StateData.CERTIFIED_SCORE_LENGTH_DAY)));
            List<CertifiedScoreDto> dtos = new ArrayList<>();
            for (CertifiedInfoDto certified : certifieds) {
                CertifiedScoreDto dto = new CertifiedScoreDto(certified.getCertifiedInfoId());

                // 统计certifiedInfoId的分数
                List<OrderComment> certifiedComments = comments.stream().filter(o -> Objects.equals(o.getReplyId(), certified.getCertifiedInfoId())).collect(Collectors.toList());
                int commentsNum = certifiedComments.size();
                Integer commentsTotal = 0;
                for (OrderComment certifiedComment : certifiedComments) {
                    commentsTotal += certifiedComment.getCommentScore();
                }
                if(commentsNum==0) dto.setCertifiedInfoScore(new BigDecimal(StateData.COMMENT_SCORE_OK));
                else{
                    dto.setCertifiedInfoScore(new BigDecimal(commentsTotal).divide(new BigDecimal(commentsNum),2, RoundingMode.HALF_UP));
                }

                dtos.add(dto);
            }


            basicInfoUtil.certifiedScoring(new CertifiedScoreForm(dtos));
        }
    }
}
